home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / GAMES / C014.ZIP / LARN_SRC.ZIP / FORTUNE.C < prev    next >
C/C++ Source or Header  |  1993-11-17  |  4KB  |  165 lines

  1. /* fortune.c */
  2. #ifdef VMS
  3. #include <types.h>
  4. #include <stat.h>
  5. #include <file.h>
  6. #else
  7. # include <sys/types.h>
  8. # include <sys/stat.h>
  9. # ifndef BSD4.1
  10. #  include <fcntl.h>
  11. # else BSD4.1
  12. # define O_RDONLY 0
  13. # endif BSD4.1
  14. #endif VMS
  15.  
  16. #include "header.h"
  17. #include "player.h"
  18. #include "larndefs.h"
  19. extern char fortfile[];
  20.  
  21. outfortune()
  22.     {
  23.     char *p;
  24.  
  25.     lprcat("\nThe cookie was delicious.");
  26.     if (c[BLINDCOUNT])
  27.         return;
  28. #ifdef MSDOS
  29.     msdosfortune();
  30. #else
  31.     if (p=fortune(fortfile))
  32.         {
  33.         lprcat("  Inside you find a scrap of paper that says:\n");
  34.         lprcat(p);
  35.         }
  36. #endif
  37.     }
  38.  
  39. # ifdef MSDOS
  40. # include <stdio.h>
  41. /* Rumors has been entirely rewritten to be disk based.  This is marginally
  42.  * slower, but requires no mallocked memory.  Notice this in only valid for
  43.  * files smaller than 32K.
  44.  */
  45. static int fortsize = 0;
  46.  
  47. static msdosfortune()
  48. {
  49.     int fd, status, i;
  50.     char    buf[BUFSIZ], ch;
  51.  
  52.     if (fortsize < 0)   /* We couldn't open fortunes */
  53.         return;
  54.     if ((fd = open(fortfile, O_RDONLY | O_BINARY)) >= 0) {
  55.         if (fortsize == 0)
  56.             fortsize = (int) lseek(fd, 0L, 2);
  57.         if (lseek(fd, (long) rund(fortsize), 0) < 0)
  58.             return;
  59.  
  60.         /* Skip to next newline or EOF
  61.          */
  62.         do {
  63.             status = read(fd, &ch, 1);
  64.         } while (status != EOF && ch != '\n');
  65.         if (status == EOF)
  66.             if (lseek(fd, 0L, 0) < 0) /* back to the beginning */
  67.                 return;
  68.  
  69.         /* Read in the line.  Search for CR ('\r'), not NL
  70.          */
  71.         for (i = 0; i < BUFSIZ - 1; i++)
  72.             if (read(fd, &buf[i], 1) == EOF || buf[i] == '\r')
  73.                 break;
  74.         buf[i] = '\0';
  75.  
  76.         /* And spit it out
  77.          */
  78.         lprcat("  Inside you find a scrap of paper that says:\n");
  79.         lprcat(buf);
  80.         close(fd);
  81.     } else
  82.         fortsize = -1;  /* Don't try opening it again */
  83. }
  84.  
  85. # else
  86.  
  87. /*
  88.  *  function to return a random fortune from the fortune file
  89.  */
  90. static char *base=0;    /* pointer to the fortune text */
  91. static char **flines=0; /* array of pointers to each fortune */
  92. static int fd=0;    /* true if we have load the fortune info */
  93. static int nlines=0;    /* # lines in fortune database */
  94.  
  95. static char *fortune(file)
  96. char *file;
  97. {
  98.     register char *p;
  99.     register int lines,tmp;
  100.     struct stat stat;
  101.     void *malloc();
  102.  
  103.     if (fd == 0) {
  104.         if ((fd=open(file,O_RDONLY)) < 0)   /* open the file */
  105.             return(0); /* can't find file */
  106.  
  107.         /* find out how big fortune file is and get memory for it */
  108.         stat.st_size = 16384;
  109.         if ((fstat(fd,&stat) < 0)
  110.         || ((base=(char *)malloc(1+stat.st_size)) == 0)) {
  111.             close(fd);
  112.             fd= -1;
  113.             free((char*)base);
  114.             return(0);  /* can't stat file */
  115.         }
  116.  
  117.         /* read in the entire fortune file */
  118. #ifdef VMS
  119.         /*
  120.          * fstat lies about the size (each record has up to
  121.          * three bytes of fill reported as actual size).
  122.          * vread returns correct size.
  123.          */
  124.         stat.st_size = vread(fd,base,stat.st_size);
  125.         if (stat.st_size <= 0)
  126. #else
  127.         if (vread(fd,base,stat.st_size) != stat.st_size)
  128. #endif
  129.         {
  130.             close(fd);
  131.             fd= -1;
  132.             free((char*)base);
  133.             return(0);  /* can't read file */
  134.         }
  135.         close(fd);
  136.         base[stat.st_size]=0;   /* final NULL termination */
  137.  
  138.         /* count up all the lines (and 0 terminate) to know memory
  139.          * needs
  140.          */
  141.         for (p=base,lines=0; p<base+stat.st_size; p++) /* count lines */
  142.             if (*p == '\n') *p=0,lines++;
  143.         nlines = lines;
  144.  
  145.         /* get memory for array of pointers to each fortune */
  146.         if ((flines=(char**)malloc(nlines*sizeof(char*))) == 0) {
  147.             free((char*)base);
  148.             fd= -1;
  149.             return(0); /* malloc() failure */
  150.         }
  151.  
  152.         /* now assign each pointer to a line */
  153.         for (p=base,tmp=0; tmp<nlines; tmp++)
  154.             {
  155.             flines[tmp]=p;  while (*p++); /* advance to next line */
  156.             }
  157.     }
  158.  
  159.     if (fd > 2) /* if we have a database to look at */
  160.         return(flines[rund((nlines<=0)?1:nlines)]);
  161.     else
  162.         return(0);
  163. }
  164. # endif
  165.